package com.atguigu.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.config.ConstantPropertiesUtils;
import com.atguigu.config.HttpClient;
import com.atguigu.service.OrderService;
import com.atguigu.service.PaymentService;
import com.atguigu.service.RefundInfoService;
import com.atguigu.service.WeiXinService;
import com.atguigu.yygh.enums.PaymentTypeEnum;
import com.atguigu.yygh.enums.RefundStatusEnum;
import com.atguigu.yygh.model.order.OrderInfo;
import com.atguigu.yygh.model.order.PaymentInfo;
import com.atguigu.yygh.model.order.RefundInfo;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class WeiXinServiceImpl implements WeiXinService {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    private OrderService orderService;
    @Autowired
    PaymentService paymentService;

    @Override
    public Map orderPayStatus(Long orderId) {
        //1 从redis里面拿支付链接
        Map map = (Map) redisTemplate.boundValueOps(orderId).get();
        if (map != null) {
            return map;
        }
        //2、为订单创建支付记录 `yygh_order`.`payment_info`
        // （注意：每一个订单最多只能有一个支付记录）
        OrderInfo orderInfo = orderService.getById(orderId);
        paymentService.savePaymentInfo(orderInfo, PaymentTypeEnum.WEIXIN.getStatus());
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("appid", ConstantPropertiesUtils.APPID);
        paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); //添加 微信支付的依赖
        String reserveDateString = new DateTime(orderInfo.getReserveDate()).toString("yyyy/MM/dd");
        String body = reserveDateString + "就诊" + orderInfo.getDepname();
        paramMap.put("body", body);
        paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
        BigDecimal amount = orderInfo.getAmount();//就诊金额
        long total_fee = 1;
        paramMap.put("total_fee", total_fee + "");//测试支付1分
        //创建本地支付的
        paramMap.put("total_fee", total_fee + "");//测试微信支付一分
        paramMap.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify");
        paramMap.put("trade_type", "NATIVE");
        //将map转化为 xml格式
        try {
            String s = WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY);
            //调用微信端 统一下单接口
            String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            //调用微信端 统一下单接口
            HttpClient httpClient = new HttpClient(url);
            //设置协议
            httpClient.setHttps(true);
            httpClient.setXmlParam(s);
            httpClient.post();
            //解析微信端返回
            String content = httpClient.getContent();
            Map<String, String> stringMap = WXPayUtil.xmlToMap(content);
            //将微信端返回的信息 封装在 map集合中
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("codeUrl", stringMap.get("code_url"));
            resultMap.put("orderId", orderId);
            resultMap.put("totalFee", orderInfo.getAmount());
            resultMap.put("resultCode", resultMap.get("result_code"));//SUCCESS/FAIL

            //8、返回结果存入到redis中
            redisTemplate.boundValueOps(orderId).set(resultMap, 5, TimeUnit.MINUTES);

            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 查看订单的支付状态
     *
     * @param orderId
     * @return
     */
    @Override
    public Map queryPayStatus(Long orderId) {
        try {
            OrderInfo orderInfo = orderService.getById(orderId);
            //封装参数
            Map paramMap = new HashMap<>();
            paramMap.put("appid", ConstantPropertiesUtils.APPID);
            paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
            paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr());

            //3、调用微信端查询支付状态接口
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, ConstantPropertiesUtils.PARTNERKEY));
            client.setHttps(true);
            client.post();
            //微信端返回值转化为 map
            String xml = client.getContent();
            Map<String, String> stringMap = WXPayUtil.xmlToMap(xml);
            return   stringMap;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    @Autowired
    private RefundInfoService  refundInfoService;
    @Override
    public Boolean refund(Long orderId) {
        try {
        //1 查看支付记录
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(orderId, PaymentTypeEnum.WEIXIN.getStatus());
        //2、根据支付记录创建退款记录
        RefundInfo refundInfo = refundInfoService.saveRefundInfo(paymentInfo);
        //3、判断退款状态--是否已退款REFUND
        if(refundInfo.getRefundStatus().intValue()== RefundStatusEnum.REFUND.getStatus().intValue()){
            return  true;
        }
        //封装退款的参数
        Map<String,String> paramMap =new HashMap<>();
        paramMap.put("appid",ConstantPropertiesUtils.APPID); //公众账号ID
        paramMap.put("mch_id",ConstantPropertiesUtils.PARTNER); //商户编号
        paramMap.put("nonce_str",WXPayUtil.generateNonceStr()); //随机字符串
        paramMap.put("transaction_id",paymentInfo.getTradeNo()); //微信订单号
        paramMap.put("out_trade_no",paymentInfo.getOutTradeNo()); //商户订单编号
        paramMap.put("out_refund_no","tk"+paymentInfo.getOutTradeNo()); //商户退款单号
        paramMap.put("total_fee","1");//订单金额
        paramMap.put("refund_fee","1");//退款金额

      //5、调用微信退款接口

            WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY);
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");
            client.setHttps(true);
            client.setCert(true);
            client.setCertPassword(ConstantPropertiesUtils.PARTNER);
            client.post();
            //6、微信返回参数
            String xml = client.getContent();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(xml);
            //7、更新退款记录状态REFUND
            if (null != resultMap && WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("result_code"))) {
                refundInfo.setTradeNo(resultMap.get("refund_id"));//微信退款单号
                refundInfo.setRefundStatus(RefundStatusEnum.REFUND.getStatus());
                refundInfo.setCallbackTime(new Date());
                refundInfo.setCallbackContent(JSONObject.toJSONString(resultMap));
                refundInfoService.updateById(refundInfo);
            }


        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        }
        return true;
    }
}
